"""
课程管理路由模块

提供教师端课程管理相关的功能，包括：
1. 页面路由：
   - /courses: 课程管理页面，显示课程列表
2. API路由：
   - GET /api/courses: 获取课程列表，支持分页和按课程名称搜索
   - GET /api/courses/<course_id>: 获取单个课程信息
   - POST /api/courses: 创建新课程
   - PUT /api/courses/<course_id>: 更新课程信息
   - DELETE /api/courses/<course_id>: 删除课程

所有API路由都需要教师登录权限，使用teacher_login_required装饰器进行保护。
"""

from flask import Blueprint, render_template, request, jsonify
from flask_login import login_required, current_user
from ..models.database import db
from ..models.models import Course, College, Teacher
from .tea_auth import teacher_login_required, add_registration
from .tea_utils import get_common_data, teacher_required

# 创建蓝图，设置URL前缀为/teacher
bp = Blueprint('teacher_course', __name__, url_prefix='/teacher')

# ==================== 页面路由 ====================
@bp.route('/courses')
@teacher_login_required
@add_registration
def courses(registration):
    """
    课程管理页面路由
    
    显示所有课程信息，支持分页显示。该路由：
    1. 需要教师登录权限
    2. 自动添加教师注册信息
    3. 显示课程列表，包含学院信息
    4. 提供分页功能
    5. 包含通用数据（学院列表等）
    
    Args:
        registration: 教师注册信息，由add_registration装饰器提供
        
    Returns:
        str: 渲染后的HTML页面，包含：
            - registration: 教师注册信息
            - courses: 分页后的课程列表
            - 其他通用数据（学院列表等）
    """
    # 获取当前页码，默认为1
    page = request.args.get('page', 1, type=int)
    # 每页显示20条记录
    per_page = 20
    
    # 获取所有课程和对应的学院名称，按课程编号降序排序
    courses_query = Course.query.join(College).add_columns(College.college_name).order_by(Course.course_id.desc())
    # 分页处理
    pagination = courses_query.paginate(page=page, per_page=per_page)
    
    # 获取通用数据（如学院列表等）
    common_data = get_common_data()
    common_data.pop('courses', None)  # 移除courses键，避免重复
    
    # 渲染模板
    return render_template('teacher/courses.html',
                         registration=registration,
                         courses=pagination,
                         **common_data)

# ==================== API路由 ====================
@bp.route('/api/courses')
@teacher_login_required
def get_courses():
    """
    获取课程列表的API
    
    支持以下功能：
    1. 分页显示课程列表
    2. 按课程名称搜索
    3. 返回课程信息和对应的学院名称
    
    Query Parameters:
        page (int): 当前页码，默认为1
        search (str): 搜索关键词，用于按课程名称搜索
        
    Returns:
        dict: JSON响应，包含：
            - success: 请求是否成功
            - courses: [
                {
                    'course_id': int,
                    'course_name': str,
                    'credits': float,
                    'semester': str,
                    'college_name': str
                },
                ...
            ]
            - pagination: {
                'total': int,      # 总记录数
                'pages': int,      # 总页数
                'current_page': int,  # 当前页码
                'has_prev': bool,  # 是否有上一页
                'has_next': bool,  # 是否有下一页
                'prev_num': int,   # 上一页页码
                'next_num': int    # 下一页页码
            }
    """
    # 获取分页参数
    page = request.args.get('page', 1, type=int)
    # 获取搜索参数
    search_text = request.args.get('search', '')
    
    # 构建基础查询
    query = db.session.query(
        Course,
        College.college_name
    ).join(
        College, Course.college_id == College.college_id
    )
    
    # 如果有搜索文本，添加课程名过滤条件
    if search_text:
        query = query.filter(Course.course_name.ilike(f'%{search_text}%'))
    
    # 按课程编号降序排序
    query = query.order_by(Course.course_id.desc())
    
    # 获取分页结果
    pagination = query.paginate(page=page, per_page=20)
    
    # 构建返回数据
    courses = []
    for course, college_name in pagination.items:
        courses.append({
            'course_id': course.course_id,
            'course_name': course.course_name,
            'credits': course.credits,
            'semester': course.semester,
            'college_name': college_name
        })
    
    return jsonify({
        'success': True,
        'courses': courses,
        'pagination': {
            'total': pagination.total,
            'pages': pagination.pages,
            'current_page': pagination.page,
            'has_prev': pagination.has_prev,
            'has_next': pagination.has_next,
            'prev_num': pagination.prev_num,
            'next_num': pagination.next_num
        }
    })

@bp.route('/api/courses/<int:course_id>', methods=['GET'])
@teacher_login_required
def get_course(course_id):
    """
    获取单个课程信息的API
    
    根据课程ID获取详细信息，包括：
    - 课程ID
    - 课程名称
    - 所属学院ID和名称
    - 学分
    - 学期
    
    Args:
        course_id (int): 课程ID
        
    Returns:
        dict: JSON响应，包含：
            - success: 请求是否成功
            - data: {
                'course_id': int,
                'course_name': str,
                'college_id': int,
                'college_name': str,
                'credits': float,
                'semester': str
            }
            或
            - message: 错误信息（如果请求失败）
            
    Raises:
        404: 课程不存在
        500: 服务器内部错误
    """
    try:
        # 使用join查询一次性获取课程和学院信息
        course = db.session.query(
            Course,
            College.college_name
        ).join(
            College, Course.college_id == College.college_id
        ).filter(
            Course.course_id == course_id
        ).first_or_404()
        
        # 构建返回数据
        course_data = {
            'course_id': course[0].course_id,
            'course_name': course[0].course_name,
            'college_id': course[0].college_id,
            'college_name': course[1],
            'credits': course[0].credits,
            'semester': course[0].semester
        }
        
        return jsonify({
            'success': True,
            'data': course_data
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'获取课程信息失败: {str(e)}'
        }), 500

@bp.route('/api/courses', methods=['POST'])
@teacher_login_required
def create_course():
    """
    创建新课程的API
    
    创建新的课程记录，需要提供：
    - 课程名称
    - 所属学院ID
    - 学分
    - 学期
    
    该API会：
    1. 验证必要字段
    2. 检查学院是否存在
    3. 检查课程名称是否重复
    4. 创建新课程记录
    
    Request Body:
        {
            'course_name': str,   # 课程名称
            'college_id': int,    # 学院ID
            'credits': float,     # 学分
            'semester': str       # 学期
        }
        
    Returns:
        dict: JSON响应，包含：
            - success: 请求是否成功
            - data: 新创建的课程信息（如果成功）
            - message: 错误信息（如果失败）
            
    Status Codes:
        201: 创建成功
        400: 请求参数错误或创建失败
    """
    # 获取请求数据
    data = request.get_json()
    if not data:
        return jsonify({'success': False, 'message': '请求体为空'}), 400
    
    # 检查必要字段
    required_fields = ['course_name', 'college_id', 'credits', 'semester']
    for field in required_fields:
        if field not in data:
            return jsonify({'success': False, 'message': f'缺少必要字段: {field}'}), 400
    
    try:
        # 检查学院是否存在
        college = College.query.get(data['college_id'])
        if not college:
            return jsonify({'success': False, 'message': f'学院ID {data["college_id"]} 不存在'}), 400
            
        # 检查课程名称是否已存在
        existing_course = Course.query.filter_by(course_name=data['course_name']).first()
        if existing_course:
            return jsonify({'success': False, 'message': f'课程名称 {data["course_name"]} 已存在'}), 400
            
        # 创建新课程
        course = Course(
            course_name=data['course_name'],
            college_id=int(data['college_id']),
            credits=float(data['credits']),
            semester=data['semester']
        )
        db.session.add(course)
        db.session.commit()
        
        # 构建返回数据
        course_data = {
            'course_id': course.course_id,
            'course_name': course.course_name,
            'college_id': course.college_id,
            'credits': course.credits,
            'semester': course.semester
        }
        return jsonify({'success': True, 'data': course_data}), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': f'创建课程失败: {str(e)}'}), 400

@bp.route('/api/courses/<int:course_id>', methods=['PUT'])
@teacher_login_required
def update_course(course_id):
    """
    更新课程信息的API
    
    更新指定课程的信息，可以修改：
    - 课程名称
    - 所属学院
    - 学分
    - 学期
    
    该API会：
    1. 验证课程是否存在
    2. 检查课程名称是否与其他课程重复
    3. 更新指定字段
    4. 保存更改
    
    Args:
        course_id (int): 要更新的课程ID
        
    Request Body:
        {
            'course_name': str,   # 新的课程名称（可选）
            'college_id': int,    # 新的学院ID（可选）
            'credits': float,     # 新的学分（可选）
            'semester': str       # 新的学期（可选）
        }
        
    Returns:
        dict: JSON响应，包含：
            - success: 请求是否成功
            - data: 更新后的课程信息（如果成功）
            - message: 错误信息（如果失败）
            
    Status Codes:
        200: 更新成功
        400: 请求参数错误或更新失败
        404: 课程不存在
    """
    # 获取要更新的课程
    course = Course.query.get_or_404(course_id)
    data = request.get_json()
    if not data:
        return jsonify({'success': False, 'message': '请求体为空'}), 400
    
    try:
        # 如果更新课程名称，检查是否与其他课程重名
        if 'course_name' in data and data['course_name'] != course.course_name:
            existing_course = Course.query.filter_by(course_name=data['course_name']).first()
            if existing_course and existing_course.course_id != course_id:
                return jsonify({'success': False, 'message': f'课程名称 {data["course_name"]} 已存在'}), 400
            course.course_name = data['course_name']
            
        # 更新其他字段
        if 'college_id' in data:
            # 检查学院是否存在
            college = College.query.get(data['college_id'])
            if not college:
                return jsonify({'success': False, 'message': f'学院ID {data["college_id"]} 不存在'}), 400
            course.college_id = int(data['college_id'])
            
        if 'credits' in data:
            course.credits = float(data['credits'])
            
        if 'semester' in data:
            course.semester = data['semester']
            
        db.session.commit()
        
        # 构建返回数据
        course_data = {
            'course_id': course.course_id,
            'course_name': course.course_name,
            'college_id': course.college_id,
            'credits': course.credits,
            'semester': course.semester
        }
        return jsonify({'success': True, 'data': course_data})
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': str(e)}), 400

@bp.route('/api/courses/<int:course_id>', methods=['DELETE'])
@teacher_login_required
def delete_course(course_id):
    """
    删除课程的API
    
    删除指定的课程记录。该API会：
    1. 验证课程是否存在
    2. 删除课程记录
    3. 处理可能的关联数据（如成绩记录）
    
    Args:
        course_id (int): 要删除的课程ID
        
    Returns:
        dict: JSON响应，包含：
            - success: 请求是否成功
            - message: 成功或错误信息
            
    Status Codes:
        200: 删除成功
        400: 删除失败
        404: 课程不存在
        
    Note:
        删除课程可能会影响关联的成绩记录，需要谨慎操作
    """
    # 获取要删除的课程
    course = Course.query.get_or_404(course_id)
    try:
        # 删除课程
        db.session.delete(course)
        db.session.commit()
        return jsonify({'success': True, 'message': '删除成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'success': False, 'message': str(e)}), 400